package com.cbs.android.module.discussion.activity;

import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.cbs.android.component.application.activity.CBSActivity;
import com.cbs.android.component.application.activity.CBSDialogFragment;
import com.cbs.android.component.application.activity.delayedtask.DelayedTask;
import com.cbs.android.component.application.activity.handler.CBSSimpleActivityResultHandler;
import com.cbs.android.component.applicationutils.Global;
import com.cbs.android.component.log.L;
import com.cbs.android.component.network.HttpClient;
import com.cbs.android.component.network.Request;
import com.cbs.android.component.network.SimpleResponseHandler;
import com.cbs.android.component.network.decoder.GsonDecoder;
import com.cbs.android.component.toast.Toast;
import com.cbs.android.extension.glide.target.RoundedImageViewTarget;
import com.cbs.android.extension.glide.urlloader.qiniu.QiniuUrlLoader;
import com.cbs.android.extension.glide.urlloader.qiniu.url.AvatarUrl;
import com.cbs.android.extension.recyclerviewadapter.RecyclerViewAdapter;
import com.cbs.android.function.input.ButtonDialogFragment;
import com.cbs.android.module.discussion.DiscussionModule;
import com.cbs.android.module.discussion.R;
import com.cbs.android.module.discussion.entity.Comment;
import com.cbs.android.module.discussion.entity.CommentSnapshot;
import com.cbs.android.module.discussion.entity.Reply;
import com.cbs.android.module.discussion.entity.ReplySnapshot;
import com.cbs.android.module.discussion.entity.Star;
import com.cbs.android.module.discussion.entity.StarSnapshot;
import com.cbs.android.module.discussion.entity.SubjectSnapshot;
import com.cbs.android.module.discussion.entity.UnStarSnapshot;
import com.cbs.android.module.discussion.utils.Constants;
import com.cbs.android.module.discussion.utils.DiscussionActivityType;
import com.cbs.android.module.discussion.utils.SimpleJsonCombiner;
import com.cbs.android.module.user.network.CBSUserRequest;
import com.cbs.android.module.user.user.UserModule;
import com.cbs.android.module.user.user.entity.User;
import com.cbs.android.module.userkit.UserKit;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import cn.bingoogolapple.refreshlayout.BGANormalRefreshViewHolder;
import cn.bingoogolapple.refreshlayout.BGARefreshLayout;
import okhttp3.CacheControl;
import okhttp3.FormBody;
import okhttp3.RequestBody;

/**
 * Created by broche on 9/24/15.
 */
// TODO 403 forbidden 处理
public abstract class DiscussionListActivity<Subject> extends CBSActivity implements View.OnClickListener {
    private static final String TAG = DiscussionListActivity.class.getName();
    private static final String CommentsUrlTpl = "social/api/v1/forums/%d/subjects/%d/comments?pageno=0&pagesize=999&replycount=%d";
    private static final String CommentsTopUrlTpl = "social/api/v1/forums/%d/subjects/%d/comments/top?pageno=0&pagesize=5&replycount=%d";
    private static final String StarUrlTpl = "social/api/v1/forums/%d/subjects/%d/comments/%d/stars";
    private static final String UnStarUrlTpl = "social/api/v1/forums/%d/subjects/%d/comments/%d/stars/%d";
    private static final String ReportUrlTpl = "social/api/v1/forums/%d/subjects/%d/comments/%d/reports";

    protected abstract int getForumId();

    protected abstract Class<? extends DiscussionDetailActivity> getDetailActivityClass();

    protected abstract Subject onGetData(Context context, int subjectId);

    protected abstract View onCreateView(Context context, ViewGroup viewGroup);

    protected abstract void onBindView(Context context, View view, Subject data);

    protected abstract SubjectSnapshot onSnapshot(Context context, Subject subject);

    protected abstract void onUserClick(Context context, int senderId);

    protected Class<? extends CommentAddActivity> getCommentAddActivityClass() {
        return CommentAddActivity.class;
    }

    private HttpClient httpClient = Global.getHttpClient().clone();
    private RefreshFinishTask refreshFinishTask = new RefreshFinishTask();

    private int subjectId = -1;
    private int replyCount = 2;
    private List<Comment> commentsTop = new ArrayList<>();
    private List<Comment> comments = new ArrayList<>();
    private Subject subjectObject = null;

    private View subjectView = null;
    private BGARefreshLayout refreshView = null;
    private RecyclerView contentView = null;

    private MyAdapter myAdapter = new MyAdapter();

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.cbs_discussion_list);

        Intent intent = getIntent();
        subjectId = intent.getIntExtra(Constants.SubjectId, -1);

        if (subjectId < 0) {
            Toast.show(getString(R.string.cbs_discussion_hint_paramerror));
            finish();
            return;
        }

        httpClient.setDebug(DiscussionModule.isDebug());

        refreshView = (BGARefreshLayout) findViewById(R.id.cbs_discussion_list_refresh);
        contentView = (RecyclerView) findViewById(R.id.cbs_discussion_list_list);
        contentView.setLayoutManager(new LinearLayoutManager(this));
        subjectView = onCreateView(this, contentView);
        View emptyView = getLayoutInflater().inflate(R.layout.cbs_discussion_emptycomment, contentView, false);

        myAdapter.setHeaderView(subjectView);
        myAdapter.setEmptyView(emptyView);

        contentView.setAdapter(myAdapter);
        refreshView.setRefreshViewHolder(new BGANormalRefreshViewHolder(this, true));
        refreshView.setDelegate(new MyDelegate());

        findViewById(R.id.cbs_discussion_list_back).setOnClickListener(this);
        findViewById(R.id.cbs_discussion_list_comment).setOnClickListener(this);

        refreshView.beginRefreshing();
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.cbs_discussion_list_back) {
            finish();
        } else if (v.getId() == R.id.cbs_discussion_list_comment) {
            if (UserModule.getUser() == null) {
                UserKit.login(DiscussionListActivity.this, new CBSSimpleActivityResultHandler() {
                    @Override
                    public void onSuccess(int requestCode, Intent data) {
                        Toast.show(getString(R.string.cbs_discussion_hint_loginsuccess));
                    }

                    @Override
                    public void onCancel(int requestCode, Intent data) {
                        Toast.show(getString(R.string.cbs_discussion_hint_logincanceled));
                    }
                });
                return;
            }
            if (subjectObject == null) {
                Toast.show(getString(R.string.cbs_discussion_hint_dataloading));
                return;
            }
            SubjectSnapshot subjectSnapshot = onSnapshot(DiscussionListActivity.this, subjectObject);
            User user = UserModule.getUser();
            CommentSnapshot commentSnapshot = new CommentSnapshot()
                    .setSenderid(user.getId()).setSendernickname(user.getNickName())
                    .setSenderavatar(user.getAvatar()).setSendersex(user.getSex())
                    .setSubjectid(subjectId);
            Gson gson = new Gson();
            String commentSnapshotStr = gson.toJson(commentSnapshot);
            String subjectSnapshotStr = gson.toJson(subjectSnapshot);

            Intent intent = new Intent(DiscussionListActivity.this, getCommentAddActivityClass());
            intent.putExtra(Constants.ForumId, getForumId());
            intent.putExtra(Constants.SubjectId, subjectId);
            intent.putExtra(Constants.SubjectSnapshot, subjectSnapshotStr);
            intent.putExtra(Constants.CommentSnapshot, commentSnapshotStr);
            startActivityForResult(intent, 0, R.anim.cbs_slide_in_bottom, 0);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 0) {
            if (resultCode == RESULT_OK) {
                refreshView.beginRefreshing();
            }
        }
    }

    private void onRefreshFinish(int action) {
        Bundle bundle = new Bundle();
        bundle.putInt("action", action);
        doDelayed(refreshFinishTask, bundle);
    }

    private class RefreshFinishTask implements DelayedTask {
        private int refreshCounter = 0;

        @Override
        public void doDelayed(Bundle data) {
            int action = data.getInt("action");
            if (action == 0) {
                refreshCounter = 0;
            } else {
                refreshCounter++;
                if (refreshCounter >= 3) {
                    refreshView.endRefreshing();
                }
            }
        }
    }

    private class MyDelegate implements BGARefreshLayout.BGARefreshLayoutDelegate {
        @Override
        public void onBGARefreshLayoutBeginRefreshing(BGARefreshLayout bgaRefreshLayout) {
            onRefreshFinish(0);
            Request requestComments = new CBSUserRequest(String.format(Global.getServerHost() + "/" + CommentsUrlTpl, getForumId(), subjectId, replyCount))
                    .setDecoder(new GsonDecoder(new TypeToken<List<Comment>>() {
                    }.getType()))
                    .cacheControl(CacheControl.FORCE_NETWORK)
                    .setResponseHandler(new SimpleResponseHandler<List<Comment>>() {
                        @Override
                        public void onSuccess(List<Comment> entity) {
                            DiscussionListActivity.this.comments.clear();
                            DiscussionListActivity.this.comments.addAll(entity);

                            myAdapter.notifyDataSetChanged();

                            onRefreshFinish(1);
                        }

                        @Override
                        public void onFailure(int code, String message) {
                            Toast.show("加载失败");
                            onRefreshFinish(1);
                        }

                        @Override
                        public void onException(Request request, Exception e) {
                            super.onException(request, e);
                            onRefreshFinish(1);
                        }
                    });
            httpClient.send(requestComments);

            Request requestCommentsTop = new CBSUserRequest(String.format(Global.getServerHost() + "/" + CommentsTopUrlTpl, getForumId(), subjectId, replyCount))
                    .setDecoder(new GsonDecoder(new TypeToken<List<Comment>>() {
                    }.getType()))
                    .cacheControl(CacheControl.FORCE_NETWORK)
                    .setResponseHandler(new SimpleResponseHandler<List<Comment>>() {
                        @Override
                        public void onSuccess(List<Comment> entity) {
                            DiscussionListActivity.this.commentsTop.clear();
                            DiscussionListActivity.this.commentsTop.addAll(entity);

                            myAdapter.notifyDataSetChanged();

                            onRefreshFinish(1);
                        }

                        @Override
                        public void onFailure(int code, String message) {
                            Toast.show("加载失败");
                            onRefreshFinish(1);
                        }

                        @Override
                        public void onException(Request request, Exception e) {
                            super.onException(request, e);
                            onRefreshFinish(1);
                        }
                    });
            httpClient.send(requestCommentsTop);

            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    subjectObject = onGetData(DiscussionListActivity.this, subjectId);
                    doDelayed(new DelayedTask() {
                        @Override
                        public void doDelayed(Bundle data) {
                            myAdapter.notifyDataSetChanged();
                            onBindView(DiscussionListActivity.this, subjectView, subjectObject);
                            onRefreshFinish(1);
                        }
                    });
                }
            });
            thread.start();
        }

        @Override
        public boolean onBGARefreshLayoutBeginLoadingMore(BGARefreshLayout bgaRefreshLayout) {
            return false;
        }
    }

    private class MyAdapter extends RecyclerViewAdapter {
        private static final int Section1 = 0;
        private static final int Item1 = 1;
        private static final int Section2 = 2;
        private static final int Item2 = 3;

        @Override
        protected RecyclerView.ViewHolder onCreateContentViewHolder(ViewGroup parent, int viewType) {
            if (viewType == Section1) {
                View view = getLayoutInflater().inflate(R.layout.cbs_discussion_list_section, parent, false);
                return new SectionHolder(view);
            } else if (viewType == Item1) {
                View view = getLayoutInflater().inflate(R.layout.cbs_discussion_list_item, parent, false);
                return new ItemViewHolder(view);
            } else if (viewType == Section2) {
                View view = getLayoutInflater().inflate(R.layout.cbs_discussion_list_section, parent, false);
                return new SectionHolder(view);
            } else {
                View view = getLayoutInflater().inflate(R.layout.cbs_discussion_list_item, parent, false);
                return new ItemViewHolder(view);
            }
        }

        @Override
        protected void onBindContentViewHolder(RecyclerView.ViewHolder holder, int position) {
            int viewType = getContentViewType(position);
            if (viewType == Section1) {
                SectionHolder sectionHolder = ((SectionHolder) holder);
                sectionHolder.titleView.setText(R.string.cbs_discussion_label_hotest);
            } else if (viewType == Item1) {
                position -= 1;
                if (position >= 0) {
                    Comment comment = commentsTop.get(position);
                    ItemViewHolder itemViewHolder = ((ItemViewHolder) holder);
                    bindItemView(itemViewHolder, comment);
                }
            } else if (viewType == Section2) {
                SectionHolder sectionHolder = ((SectionHolder) holder);
                sectionHolder.titleView.setText(R.string.cbs_discussion_label_newest);
            } else {
                if (commentsTop.size() > 0) {
                    position -= 1;
                    position -= commentsTop.size();
                }
                position -= 1;
                if (position >= 0) {
                    Comment comment = comments.get(position);
                    ItemViewHolder itemViewHolder = ((ItemViewHolder) holder);
                    bindItemView(itemViewHolder, comment);
                }
            }
        }

        private void bindItemView(ItemViewHolder itemViewHolder, Comment comment) {
            // data
            Glide.with(DiscussionListActivity.this)
                    .using(new QiniuUrlLoader(DiscussionListActivity.this))
                    .load(new AvatarUrl(DiscussionModule.getAvatarPath(comment.getSenderAvatar())))
                    .asBitmap()
                    .placeholder(R.drawable.cbs_discussion_avatar)
                    .error(R.drawable.cbs_discussion_avatar)
                    .into(new RoundedImageViewTarget(itemViewHolder.senderAvatarView));

            itemViewHolder.senderNicknameView.setText(comment.getSenderNickName());
            itemViewHolder.senderSexView.setImageResource(comment.getSenderSex() == 0 ? R.drawable.cbs_discussion_sex_female_default : R.drawable.cbs_discussion_sex_male_default);
            itemViewHolder.timestampView.setText(DiscussionModule.getDateFormatter().format(comment.getTimestamp()));
            itemViewHolder.starView.setImageResource(R.drawable.cbs_discussion_star_unstared_default);
            int userid = 0;
            if (UserModule.getUser() != null) {
                userid = UserModule.getUser().getId();
            }
            for (Star star : comment.getStars()) {
                if (star.getUserId() == userid) {
                    itemViewHolder.starView.setImageResource(R.drawable.cbs_discussion_star_stared_default);
                    break;
                }
            }
            itemViewHolder.starCountView.setText(comment.getStarCount() + "");
            itemViewHolder.contentView.setText(comment.getContent());
            if (comment.getReplyCount() > 0) {
                itemViewHolder.replyContainerView.setVisibility(View.VISIBLE);
                if (comment.getReplyCount() > 2) {
                    itemViewHolder.moreView.setVisibility(View.VISIBLE);
                    itemViewHolder.moreCountView.setText((comment.getReplyCount() - 2) + "");
                } else {
                    itemViewHolder.moreView.setVisibility(View.GONE);
                }

                itemViewHolder.repliesView.removeAllViews();
                for (Reply reply : comment.getReplies()) {
                    View replyView = getLayoutInflater().inflate(R.layout.cbs_discussion_list_item_reply, itemViewHolder.repliesView, false);
                    TextView replyContentView = (TextView) replyView.findViewById(R.id.cbs_discussion_list_item_reply_content);
                    String content;
                    int blue;
                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                        blue = getColor(R.color.cbs_discussion_reply_blue);
                    } else {
                        blue = getResources().getColor(R.color.cbs_discussion_reply_blue);
                    }
                    int darkgrey;
                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                        darkgrey = getColor(R.color.cbs_discussion_reply_darkgrey);
                    } else {
                        darkgrey = getResources().getColor(R.color.cbs_discussion_reply_darkgrey);
                    }
                    int grey;
                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                        grey = getColor(R.color.cbs_discussion_reply_grey);
                    } else {
                        grey = getResources().getColor(R.color.cbs_discussion_reply_grey);
                    }
                    int size1 = (int) getResources().getDimension(R.dimen.cbs_discussion_reply_content_sender);
                    int size2 = (int) getResources().getDimension(R.dimen.cbs_discussion_reply_content);
                    if (reply.getConsigneeId() == -1) {
                        content = String.format(getResources().getString(R.string.cbs_discussion_reply_content_1), blue, size1, reply.getSenderNickName(), darkgrey, size1, reply.getContent(), grey, size2, DiscussionModule.getDateFormatter().format(reply.getTimestamp()));
                    } else {
                        content = String.format(getResources().getString(R.string.cbs_discussion_reply_content_2), blue, size1, reply.getSenderNickName(), darkgrey, size1, blue, size1, reply.getConsigneeNickName(), darkgrey, size1, reply.getContent(), grey, size2, DiscussionModule.getDateFormatter().format(reply.getTimestamp()));
                    }
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        replyContentView.setText(Html.fromHtml(content, Html.FROM_HTML_MODE_COMPACT));
                    } else {
                        replyContentView.setText(Html.fromHtml(content));
                    }
                    itemViewHolder.repliesView.addView(replyView);
                }
            } else {
                itemViewHolder.replyContainerView.setVisibility(View.GONE);
            }

            // listener
            itemViewHolder.senderView.setTag(comment);
            itemViewHolder.starContainerView.setTag(comment);
            itemViewHolder.contentView.setTag(comment);
            itemViewHolder.replyContainerView.setTag(comment);
        }

        @Override
        protected int getContentViewType(int position) {
            if (commentsTop.size() == 0) {
                if (position == 0) {
                    return Section2;
                } else {
                    return Item2;
                }
            } else {
                if (position == 0) {
                    return Section1;
                } else if (position < commentsTop.size() + 1) {
                    return Item1;
                } else if (position == commentsTop.size() + 1) {
                    return Section2;
                } else {
                    return Item2;
                }
            }
        }

        @Override
        public int getContentCount() {
            int count = 0;
            if (commentsTop.size() > 0) {
                count += commentsTop.size();
                count += 1;
            }
            if (comments.size() > 0) {
                count += comments.size();
                count += 1;
            }
            return count;
        }

        public void notifyTopItemChanged(Comment comment) {
            int position = getPosition(comment, true);
            if (position >= 0) {
                notifyContentChanged(position);
            }
        }

        public void notifyItemChanged(Comment comment) {
            int position = getPosition(comment, false);
            if (position >= 0) {
                notifyContentChanged(position);
            }
        }

        private int getPosition(Comment comment, boolean isTop) {
            if (isTop) {
                for (int i = 0; i < commentsTop.size(); i++) {
                    Comment tcomment = commentsTop.get(i);
                    if (tcomment.getId() == comment.getId()) {
                        return i + 1;
                    }
                }
            } else {
                for (int i = 0; i < comments.size(); i++) {
                    Comment tcomment = comments.get(i);
                    if (tcomment.getId() == comment.getId()) {
                        if (commentsTop.size() > 0) {
                            return i + 1 + commentsTop.size() + 1;
                        } else {
                            return i + 1;
                        }
                    }
                }
            }
            return -1;
        }

        private class SectionHolder extends RecyclerView.ViewHolder {
            public TextView titleView;

            public SectionHolder(View itemView) {
                super(itemView);
                titleView = (TextView) itemView.findViewById(R.id.cbs_discussion_list_section_title);
            }
        }

        private class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
            public LinearLayout senderView = null;
            public ImageView senderAvatarView = null;
            public TextView senderNicknameView = null;
            public ImageView senderSexView = null;
            public TextView timestampView = null;
            public LinearLayout starContainerView = null;
            public ImageView starView = null;
            public TextView starCountView = null;
            public TextView contentView = null;
            public LinearLayout replyContainerView = null;
            public LinearLayout repliesView = null;
            public LinearLayout moreView = null;
            public TextView moreCountView = null;

            public ItemViewHolder(View itemView) {
                super(itemView);
                senderView = (LinearLayout) itemView.findViewById(R.id.cbs_discussion_list_item_sender);
                senderAvatarView = (ImageView) itemView.findViewById(R.id.cbs_discussion_list_item_senderavatar);
                senderNicknameView = (TextView) itemView.findViewById(R.id.cbs_discussion_list_item_sendernickname);
                senderSexView = (ImageView) itemView.findViewById(R.id.cbs_discussion_list_item_sendersex);
                timestampView = (TextView) itemView.findViewById(R.id.cbs_discussion_list_item_timestamp);
                starContainerView = (LinearLayout) itemView.findViewById(R.id.cbs_discussion_list_item_starcontainer);
                starView = (ImageView) itemView.findViewById(R.id.cbs_discussion_list_item_star);
                starCountView = (TextView) itemView.findViewById(R.id.cbs_discussion_list_item_starcount);
                contentView = (TextView) itemView.findViewById(R.id.cbs_discussion_list_item_content);
                replyContainerView = (LinearLayout) itemView.findViewById(R.id.cbs_discussion_list_item_replycontainer);
                repliesView = (LinearLayout) itemView.findViewById(R.id.cbs_discussion_list_item_replies);
                moreView = (LinearLayout) itemView.findViewById(R.id.cbs_discussion_list_item_more);
                moreCountView = (TextView) itemView.findViewById(R.id.cbs_discussion_list_item_morecount);

                senderView.setOnClickListener(this);
                starContainerView.setOnClickListener(this);
                contentView.setOnClickListener(this);
                replyContainerView.setOnClickListener(this);
            }

            private int commentId;

            @Override
            public void onClick(View view) {
                if (view.getId() == R.id.cbs_discussion_list_item_sender) {
                    int senderId = ((Comment) view.getTag()).getSenderId();
                    onUserClick(DiscussionListActivity.this, senderId);
                } else if (view.getId() == R.id.cbs_discussion_list_item_starcontainer) {
                    if (UserModule.getUser() == null) {
                        UserKit.login(DiscussionListActivity.this, new CBSSimpleActivityResultHandler() {
                            @Override
                            public void onSuccess(int requestCode, Intent data) {
                                Toast.show(getString(R.string.cbs_discussion_hint_loginsuccess));
                            }

                            @Override
                            public void onCancel(int requestCode, Intent data) {
                                Toast.show(getString(R.string.cbs_discussion_hint_logincanceled));
                            }
                        });
                        return;
                    }
                    if (subjectObject == null) {
                        Toast.show(getString(R.string.cbs_discussion_hint_dataloading));
                        return;
                    }
                    SubjectSnapshot subjectSnapshot = onSnapshot(DiscussionListActivity.this, subjectObject);
                    final Comment comment = (Comment) view.getTag();
                    int starId = -1;
                    for (Star star : comment.getStars()) {
                        if (star.getUserId() == UserModule.getUser().getId()) {
                            starId = star.getId();
                            break;
                        }
                    }
                    User user = UserModule.getUser();
                    Gson gson = new Gson();
                    if (starId != -1) {
                        UnStarSnapshot unstarSnapshot = new UnStarSnapshot()
                                .setCommentid(comment.getId()).setSubjectid(subjectId)
                                .setSenderid(user.getId()).setSendernickname(user.getNickName())
                                .setSenderavatar(user.getAvatar()).setSendersex(user.getSex())
                                .setConsigneeid(comment.getSenderId()).setConsigneenickname(comment.getSenderNickName())
                                .setConsigneeavatar(comment.getSenderAvatar()).setConsigneesex(comment.getSenderSex())
                                .setRefcontent(comment.getContent());
                        String unstarSnapshotStr = gson.toJson(unstarSnapshot);
                        String subjectSnapshotStr = gson.toJson(subjectSnapshot);
                        String snapshot = SimpleJsonCombiner.combineObject(unstarSnapshotStr, subjectSnapshotStr);
                        RequestBody requestBody = new FormBody.Builder()
                                .add("type", getForumId() + "_" + DiscussionActivityType.UnStar)
                                .add("consigneeid", comment.getSenderId() + "")
                                .add("snapshot", snapshot)
                                .build();
                        Request request = new CBSUserRequest(String.format(Global.getServerHost() + "/" + UnStarUrlTpl, getForumId(), subjectId, comment.getId(), starId))
                                .delete(requestBody)
                                .setResponseHandler(new SimpleResponseHandler() {
                                    @Override
                                    public void onSuccess(Object entity) {
                                        for (Comment tcomment : comments) {
                                            if (tcomment.getId() == comment.getId()) {
                                                for (Star star : tcomment.getStars()) {
                                                    if (star.getUserId() == UserModule.getUser().getId()) {
                                                        tcomment.getStars().remove(star);
                                                        int starCount = tcomment.getStarCount();
                                                        starCount--;
                                                        starCount = starCount < 0 ? 0 : starCount;
                                                        tcomment.setStarCount(starCount);
                                                        break;
                                                    }
                                                }
                                                myAdapter.notifyItemChanged(tcomment);
                                            }
                                        }
                                        for (Comment tcomment : commentsTop) {
                                            if (tcomment.getId() == comment.getId()) {
                                                for (Star star : tcomment.getStars()) {
                                                    if (star.getUserId() == UserModule.getUser().getId()) {
                                                        tcomment.getStars().remove(star);
                                                        int starCount = tcomment.getStarCount();
                                                        starCount--;
                                                        starCount = starCount < 0 ? 0 : starCount;
                                                        tcomment.setStarCount(starCount);
                                                        break;
                                                    }
                                                }
                                                myAdapter.notifyTopItemChanged(tcomment);
                                            }
                                        }
                                        Toast.show(getString(R.string.cbs_discussion_hint_unstarsuccess));
                                    }

                                    @Override
                                    public void onFailure(int code, String message) {
                                        L.e(TAG, String.format("code: %d\tmessage: %s", code, message));
                                        Toast.show(getString(R.string.cbs_discussion_hint_unstarfailure));
                                    }

                                    @Override
                                    public void onException(Request request, Exception e) {
                                        L.e(TAG, "", e);
                                        Toast.show(getString(R.string.cbs_discussion_hint_unstarfailure));
                                    }
                                });
                        httpClient.send(request);
                    } else {
                        StarSnapshot starSnapshot = new StarSnapshot()
                                .setCommentid(comment.getId()).setSubjectid(subjectId)
                                .setSenderid(user.getId()).setSendernickname(user.getNickName())
                                .setSenderavatar(user.getAvatar()).setSendersex(user.getSex())
                                .setConsigneeid(comment.getSenderId()).setConsigneenickname(comment.getSenderNickName())
                                .setConsigneeavatar(comment.getSenderAvatar()).setConsigneesex(comment.getSenderSex())
                                .setRefcontent(comment.getContent());
                        String starSnapshotStr = gson.toJson(starSnapshot);
                        String subjectSnapshotStr = gson.toJson(subjectSnapshot);
                        String snapshot = SimpleJsonCombiner.combineObject(starSnapshotStr, subjectSnapshotStr);
                        RequestBody requestBody = new FormBody.Builder()
                                .add("type", getForumId() + "_" + DiscussionActivityType.Star)
                                .add("consigneeid", comment.getSenderId() + "")
                                .add("snapshot", snapshot)
                                .build();
                        Request request = new CBSUserRequest(String.format(Global.getServerHost() + "/" + StarUrlTpl, getForumId(), subjectId, comment.getId()))
                                .setDecoder(new GsonDecoder(Star.class))
                                .post(requestBody)
                                .setResponseHandler(new SimpleResponseHandler<Star>() {
                                    @Override
                                    public void onSuccess(Star entity) {
                                        for (Comment comment : comments) {
                                            if (comment.getId() == entity.getCommentId()) {
                                                comment.getStars().add(entity);
                                                comment.setStarCount(comment.getStarCount() + 1);
                                                myAdapter.notifyItemChanged(comment);
                                                break;
                                            }
                                        }
                                        for (Comment comment : commentsTop) {
                                            if (comment.getId() == entity.getCommentId()) {
                                                comment.getStars().add(entity);
                                                comment.setStarCount(comment.getStarCount() + 1);
                                                myAdapter.notifyTopItemChanged(comment);
                                                break;
                                            }
                                        }
                                        Toast.show(getString(R.string.cbs_discussion_hint_starsuccess));
                                    }

                                    @Override
                                    public void onFailure(int code, String message) {
                                        L.e(TAG, String.format("code: %d\tmessage: %s", code, message));
                                        Toast.show(getString(R.string.cbs_discussion_hint_starfailure));
                                    }

                                    @Override
                                    public void onException(Request request, Exception e) {
                                        L.e(TAG, "", e);
                                        Toast.show(getString(R.string.cbs_discussion_hint_starfailure));
                                    }
                                });
                        httpClient.send(request);
                    }
                } else if (view.getId() == R.id.cbs_discussion_list_item_content) {
                    if (UserModule.getUser() == null) {
                        UserKit.login(DiscussionListActivity.this, new CBSSimpleActivityResultHandler() {
                            @Override
                            public void onSuccess(int requestCode, Intent data) {
                                Toast.show(getString(R.string.cbs_discussion_hint_loginsuccess));
                            }

                            @Override
                            public void onCancel(int requestCode, Intent data) {
                                Toast.show(getString(R.string.cbs_discussion_hint_logincanceled));
                            }
                        });
                        return;
                    }

                    commentId = ((Comment) view.getTag()).getId();
                    ButtonDialogFragment fragment = new ButtonDialogFragment()
                            .setItems(Arrays.asList(getResources().getStringArray(R.array.cbs_discussion_buttons)))
                            .setOnButtonListener(new ButtonDialogFragment.OnButtonListener() {
                                @Override
                                public void onButtonClick(CBSDialogFragment cbsDialogFragment, int index, String s) {
                                    if (index == 0) {
                                        reply();
                                    } else if (index == 1) {
                                        report();
                                    } else {
                                        cancel();
                                    }
                                }
                            });
                    fragment.show(getSupportFragmentManager(), "dialog");
                } else if (view.getId() == R.id.cbs_discussion_list_item_replycontainer) {
                    int commentId = ((Comment) view.getTag()).getId();
                    Intent intent = new Intent(DiscussionListActivity.this, getDetailActivityClass());
                    intent.putExtra(Constants.SubjectId, subjectId);
                    intent.putExtra(Constants.CommentId, commentId);
                    intent.putExtra(Constants.ShowInput, false);
                    startActivity(intent);
                }
            }

            private void reply() {
                Comment tcomment = null;
                for (Comment comment : commentsTop) {
                    if (comment.getId() == commentId) {
                        tcomment = comment;
                        break;
                    }
                }
                if (tcomment == null) {
                    for (Comment comment : comments) {
                        if (comment.getId() == commentId) {
                            tcomment = comment;
                            break;
                        }
                    }
                }
                if (tcomment == null) {
                    Toast.show(getString(R.string.cbs_discussion_hint_commentnotfound));
                    return;
                } else {
                    if (subjectObject == null) {
                        Toast.show(getString(R.string.cbs_discussion_hint_dataloading));
                        return;
                    }
                    SubjectSnapshot subjectSnapshot = onSnapshot(DiscussionListActivity.this, subjectObject);
                    User user = UserModule.getUser();
                    ReplySnapshot replySnapshot = new ReplySnapshot()
                            .setSubjectid(subjectId).setCommentid(commentId)
                            .setSenderid(user.getId()).setSendernickname(user.getNickName()).setSenderavatar(user.getAvatar()).setSendersex(user.getSex())
                            .setConsigneeid(-1).setConsigneenickname("").setConsigneeavatar("").setConsigneesex(1)
                            .setLastconsigneeid(-1).setLastconsigneenickname("").setLastconsigneeavatar("").setLastconsigneesex(1)
                            .setObserverid(tcomment.getSenderId()).setObservernickname(tcomment.getSenderNickName()).setObserveravatar(tcomment.getSenderAvatar()).setObserversex(tcomment.getSenderSex())
                            .setRefcontent("").setCtxcontent(tcomment.getContent());
                    Gson gson = new Gson();
                    String replySnapshotStr = gson.toJson(replySnapshot);
                    String subjectSnapshotStr = gson.toJson(subjectSnapshot);

                    Intent intent = new Intent(DiscussionListActivity.this, getDetailActivityClass());
                    intent.putExtra(Constants.SubjectId, subjectId);
                    intent.putExtra(Constants.CommentId, commentId);
                    intent.putExtra(Constants.ShowInput, true);
                    intent.putExtra(Constants.ConsigneeId, -1);
                    intent.putExtra(Constants.SubjectSnapshot, subjectSnapshotStr);
                    intent.putExtra(Constants.ReplySnapshot, replySnapshotStr);
                    startActivity(intent);
                }
            }

            private void report() {
                RequestBody requestBody = new FormBody.Builder()
                        .build();
                Request request = new CBSUserRequest(String.format(Global.getServerHost() + "/" + ReportUrlTpl, getForumId(), subjectId, commentId))
                        .post(requestBody)
                        .setResponseHandler(new SimpleResponseHandler() {
                            @Override
                            public void onSuccess(Object entity) {
                                Toast.show(getString(R.string.cbs_discussion_hint_reportsuccess));
                            }

                            @Override
                            public void onFailure(int code, String message) {
                                Toast.show(getString(R.string.cbs_discussion_hint_reportfailure));
                            }
                        });
                httpClient.send(request);
            }

            private void cancel() {
                // NO ACTION
            }
        }
    }

    protected void setTitle(String title) {
        TextView titleView = (TextView) findViewById(R.id.cbs_discussion_list_title);
        titleView.setText(title);
    }
}
